package com.yourenbang.lingyun.transaction.job.handler;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayDataBillBalanceQueryResponse;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.DingdingUtils;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.http.HttpClientUtil;
import com.yourenbang.lingyun.domain.PayType;
import com.yourenbang.lingyun.transaction.config.AcmTransactionParams;
import com.yourenbang.lingyun.transaction.config.DingdingConfig;
import com.yourenbang.lingyun.transaction.mapper.TransactionPayTypeMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.ChangeWithdrawAlipayPayChannelDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.PayTypeSwitchDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.TSPayType;
import com.yourenbang.lingyun.transaction.web.service.pay.withdraw.channel.AliWithdrawService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j
public class PayChannelSwitchHandler {

    private static final String HOST = "/pay/payTypeSwitch";
    private static final Short OPEN = new Short("1");
    private static final Short CLOSE = new Short("0");

    @Resource
    private TransactionPayTypeMapper transactionPayTypeMapper;

    @Autowired
    private AcmTransactionParams acmTransactionParams;

    @Autowired
    private DingdingConfig dingdingConfig;

    @Autowired
    private AliWithdrawService aliWithdrawService;

    /**
     * 打开支付渠道
     */
    @XxlJob("openPayChannelHandler")
    public ReturnT<String> openPayChannelHandler(String param) throws Exception {
        XxlJobLogger.log("【打开支付渠道】任务开始。。。");
        if (StringUtils.isBlank(param)) {
            XxlJobLogger.log("请输入参数");
            return ReturnT.FAIL;
        }
        JSONObject reqJson = JSONUtil.parseObj(param);
        List<PayTypeSwitchDTO> payTypeSwitchDTOs = reqJson.getJSONArray("payTypes").toList(PayTypeSwitchDTO.class);
        if (payTypeSwitchDTOs.isEmpty()) {
            XxlJobLogger.log("缺少参数");
            return ReturnT.FAIL;
        }
        int index = 0;
        for (PayTypeSwitchDTO dto : payTypeSwitchDTOs) {
            index++;
            //获取支付方式
            PayType type = transactionPayTypeMapper.getPayTypeNeedPlatNo(dto.getCode(), dto.getPayFrom(), dto.getPlatNo());
            if (Objects.isNull(type)) {
                XxlJobLogger.log("【{}】未找到支付方式", index, dto.toJSON());
                continue;
            }
            //打开支付方式
            int upcl = transactionPayTypeMapper.openPayTypeNeedPlatNo(dto.getCode(), dto.getPayFrom(), dto.getPlatNo());
            BizAssertUtils.assertOne(upcl, "打开失败");
            //同步快收库
            if (PlatNoEnums.KLKS.getCode().equals(dto.getPlatNo())
                    && StringUtils.isNotBlank(dto.getCodeKlks())
                    && StringUtils.isNotBlank(dto.getPayFromKlks())) {
                return payChannelSwitchKlks(dto.getCodeKlks(), dto.getPayFromKlks(), OPEN);
            }
            XxlJobLogger.log("【{}】支付渠道已打开：{}", index, type);
        }
        return ReturnT.SUCCESS;
    }

    /**
     * 关闭支付渠道
     */
    @XxlJob("closePayChannelHandler")
    public ReturnT<String> closePayChannelHandler(String param) throws Exception {
        XxlJobLogger.log("【关闭支付渠道】任务开始。。。");
        if (StringUtils.isBlank(param)) {
            XxlJobLogger.log("请输入参数");
            return ReturnT.FAIL;
        }
        JSONObject reqJson = JSONUtil.parseObj(param);
        List<PayTypeSwitchDTO> payTypeSwitchDTOs = reqJson.getJSONArray("payTypes").toList(PayTypeSwitchDTO.class);
        if (payTypeSwitchDTOs.isEmpty()) {
            XxlJobLogger.log("缺少参数");
            return ReturnT.FAIL;
        }
        int index = 0;
        for (PayTypeSwitchDTO dto : payTypeSwitchDTOs) {
            index++;
            //获取支付方式
            PayType type = transactionPayTypeMapper.getPayTypeNeedPlatNo(dto.getCode(), dto.getPayFrom(), dto.getPlatNo());
            if (Objects.isNull(type)) {
                XxlJobLogger.log("【{}】未找到支付方式", index, dto.toJSON());
                continue;
            }
            //关闭支付方式
            int upcl = transactionPayTypeMapper.closePayTypeNeedPlatNo(dto.getCode(), dto.getPayFrom(), dto.getPlatNo());
            BizAssertUtils.assertOne(upcl, "关闭失败");
            //同步快收库
            if (PlatNoEnums.KLKS.getCode().equals(dto.getPlatNo())
                    && StringUtils.isNotBlank(dto.getCodeKlks())
                    && StringUtils.isNotBlank(dto.getPayFromKlks())) {
                return payChannelSwitchKlks(dto.getCodeKlks(), dto.getPayFromKlks(), CLOSE);
            }
            XxlJobLogger.log("【{}】支付渠道已关闭：{}", index, type);
        }
        return ReturnT.SUCCESS;
    }

    /**
     * 凌云切换支付宝提现支付渠道
     */
    @XxlJob("changeWithdrawAlipayPayChannelHandler")
    public ReturnT<String> changeWithdrawAlipayPayChannelHandler(String param) throws Exception {
        XxlJobLogger.log("【凌云切换支付宝提现支付渠道】任务开始。。。");
        if (StringUtils.isBlank(param)) {
            XxlJobLogger.log("请输入参数");
            return ReturnT.FAIL;
        }
        ChangeWithdrawAlipayPayChannelDTO changeDTO = JSON.parseObject(param, ChangeWithdrawAlipayPayChannelDTO.class);
        if (changeDTO.getThresholdAmount() == null) {
            XxlJobLogger.log("请输入参数");
            return ReturnT.FAIL;
        }

        List<TSPayType> tsPayTypeList = transactionPayTypeMapper.withdrawAlipayList();
        if (CollectionUtils.isEmpty(tsPayTypeList)){
            XxlJobLogger.log("查询支付宝提现支付方式失败");
            return ReturnT.FAIL;
        }
        int payChannelId = tsPayTypeList.get(0).getPayChannel();
        String payChannelName = "支付宝-考拉联创-网商（证书）";
        AlipayDataBillBalanceQueryResponse alipayDataBillBalanceQueryResponse
                = aliWithdrawService.alipayDataBillBalanceQuery(payChannelId);
        if (Objects.isNull(alipayDataBillBalanceQueryResponse)){
            XxlJobLogger.log("支付宝商家账户当前余额查询失败");
            return ReturnT.FAIL;
        }
        BigDecimal availableAmount = new BigDecimal(alipayDataBillBalanceQueryResponse.getAvailableAmount());
        if (availableAmount.compareTo(changeDTO.getThresholdAmount()) >= 0){
            XxlJobLogger.log("账户余额充足，无需更改支付渠道");
            return ReturnT.SUCCESS;
        }
        if (tsPayTypeList.get(0).getPayChannel().equals(7)){
            payChannelId = 8;
            payChannelName = "支付宝-考拉联创-咨询（证书）";
        }else {
            payChannelId = 7;
        }
        int ups = transactionPayTypeMapper.changeWithdrawAlipayPayChannel(payChannelId);
        if (ups<1){
            XxlJobLogger.log("更改支付宝提现支付渠道失败");
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("支付渠道已更改为：{}", payChannelId);
        String msg = "凌云-支付宝提现渠道更改为：" +"【"+payChannelName+"】";
        DingdingUtils.sendToDingding(msg, dingdingConfig.getDingdingWarnToken());
        return ReturnT.SUCCESS;
    }

    /**
     * 同步快收库
     */
    private ReturnT<String> payChannelSwitchKlks(String payType, String payFrom, Short flag) {
        String url = acmTransactionParams.getKaolakuaishouHost() + HOST;
        PayTypeSwitchDTO dto = new PayTypeSwitchDTO();
        dto.setCode(payType);
        dto.setPayFrom(payFrom);
        dto.setFlag(flag);
        String resultJson = null;
        try {
            XxlJobLogger.log("【支付方式开关】准备请求快收,url:{}, 请求参数:{}", url, dto.toJSON());
            resultJson = HttpClientUtil.httpPostRequest(url, dto.toJSON());
            XxlJobLogger.log("【支付方式开关】快收响应:{} ,url:{}, 请求参数:{}", resultJson, url, dto.toJSON());
        } catch (Exception e) {
            XxlJobLogger.log("请求接口异常:{}", e);
        }
        JSONObject switchKlks = JSONUtil.parseObj(resultJson);
        if (resultJson != null || StringUtils.equals(switchKlks.getStr("succ"), "true")) {
            return ReturnT.SUCCESS;
        }
        String msg = "【快收支付方式开关预警】" + (flag == 1 ? "打开" : "关闭") + "失败,{code=" + payType + ",payFrom=" + payFrom + "}";
        DingdingUtils.sendToDingding(msg, dingdingConfig.getDingdingWarnToken());
        return ReturnT.FAIL;
    }
}
